/*
* SSHMeIn's javascript code for RIA interface events
* This library make intensive use of jQuery and Amplify libraries
* http://www.jquery.com/
* http://amplifyjs.com/
*/

(function ($, amplify, undefined) {

    /*Export Sshmein as global */
    var Sshmein = this.Sshmein = {};
    
    /* Detect application URL and PORT */
    Sshmein.application_url = this.location.protocol + '//' + this.location.host + '/';
    
    /*Stores all hosts and groups API*/
    Sshmein.collections = {};
    
    /*Store all Sshmein UI management*/
    Sshmein.ui = {};

    /*Store all Sshmein settings*/
    Sshmein.settings = (function(){

        var config = {
            displayMode : 'groups',
            theme : 'Dot Luv',
            notificationDelay: 2000, //time in milliseconds
            notificationOpacity : 0.8
        };

        var set = function(key, value){
            config[key] = value;
        };

        var get = function(key){
            return config[key];
        };

        return {
            set : set,
            get: get
        };

    }());//Sshmein.settings
    
    /*Groups collections API*/
    Sshmein.collections.groups = (function () {
        
        var store = {};
        var tunnelOnCounters = {};
        
        var init = function () {
            
            /*
            * All group's request definition
            */
            
            /* Fetching all groups */
            amplify.request.define('groups', 'ajax', {
                url: Sshmein.application_url + "groups/",
                dataType: 'json',
                type: 'GET'
            });
            
            /* Create a new group */
            amplify.request.define('group.create', 'ajax', {
                url: Sshmein.application_url + 'groups/new',
                dataType: 'json',
                type: 'POST'
            
            });
            
            /* Delete a group */
            amplify.request.define('group.delete', 'ajax', {
                url: Sshmein.application_url + 'groups/delete/{id}',
                type: 'GET'
            });
            
            /* Update a group */
            amplify.request.define('group.update', 'ajax', {
                url: Sshmein.application_url + 'groups/update',
                type: 'POST'
            });
        };//init()
        
        var loadAll = function () {
            tunnelOnCounters = {};
            store = {};

            amplify.request('groups', function (data) {
                for (var i=0; i<data.length; i++) {
                        Sshmein.collections.groups.add(data[i].id, data[i]);
                }
                amplify.publish('groups.load');
            });
        };//loadAll()

        var add = function (groupId, obj) {
            store[groupId] = obj;
        };//add()
        
        var create = function () {
            amplify.request('group.create', {name: 'newgroup'}, function (data) {
                add(data.id, data);
                amplify.publish('group.create', data.id);
            });
        };//create()
            
        var remove = function (groupId) {
            delete store[groupId];
            
            //Removing all host of the group from the hosts collections
            Sshmein.collections.hosts.removeAllByGroupId(groupId);
            
            //Delete in database
            amplify.request('group.delete', {id : groupId}, function () {
                amplify.publish('group.remove', groupId);
            });
            
        };//remove()
        
        var update = function (groupId, property, value) {
            store[groupId][property] = value;
    
            var data = {id: groupId};
            data[property] = value;
            amplify.request('group.update', data);
            amplify.publish('group.update', {id: groupId, 'key': property, value: value});
        };//update()
        
        var getOne = function (groupId) {
            if (store[groupId]) {
                return store[groupId];
            }
        };//getOne()
        
        var getAll = function (asArray) {
            var obj;
            
            if (asArray === true) {
                var data = [];
                
                for (obj in store) {
                    if (store.hasOwnProperty(obj)){
                        data.push(store[obj]);
                    }
                }

                return data;
                
            } else {
                return store;
            }
        };//getAll()
        
        
        var incrementTunnelOnCounters = function (groupId) {
            if (!isNaN(tunnelOnCounters[groupId])) {
                tunnelOnCounters[groupId] += 1;
            } else {
                tunnelOnCounters[groupId] = 1;
            }
            
            amplify.publish('group.counterOn.update', groupId);
        };//incrementTunnelOnCounter()
        
        var decrementTunnelOnCounters = function (groupId) {
            if (!isNaN(tunnelOnCounters[groupId]) && tunnelOnCounters[groupId] >= 2) {
                tunnelOnCounters[groupId] -= 1;
            } else {
                delete tunnelOnCounters[groupId];
            }
            
            amplify.publish('group.counterOn.update', groupId);
        };//incrementTunnelOnCounter()
        
        var getTunnelOnCounters = function () {
            return tunnelOnCounters;
        };//getTunnelOnCounters()
             
        return {
            /* Groups public methods */
        
            init : init,
            loadAll : loadAll,
            create : create,
            add : add,
            remove : remove,
            update : update,
            getOne : getOne,
            getAll : getAll,
            incrementTunnelOnCounters : incrementTunnelOnCounters,
            getTunnelOnCounters : getTunnelOnCounters,
            decrementTunnelOnCounters : decrementTunnelOnCounters,

            getAllAsArray : function () {
                return getAll(true);
            }//getAllAsArray()

        };//return object
    }());//Sshmein.collections.groups
    
    /*Hosts collections API*/
    Sshmein.collections.hosts = (function () {
        
        var store = {};
        
        var init = function () {
            /*
            * All host's request definition
            */
            
            /* Fetching all hosts */
            amplify.request.define('hosts', 'ajax', {
                url: Sshmein.application_url + "hosts/",
                dataType: 'json',
                type: "GET"
            });
               
            /* Add new host */
            amplify.request.define('host.create', 'ajax', {
                url: Sshmein.application_url + 'hosts/new/{id}',
                dataType: 'json',
                type: 'GET'
            
            });
            
            /* Delete a host */
            amplify.request.define('host.delete', 'ajax', {
                url: Sshmein.application_url + 'hosts/delete/{id}',
                type: 'GET'
            });
            
            /* Update a host */
            amplify.request.define('host.update', 'ajax', {
                url: Sshmein.application_url + 'hosts/update',
                type: 'POST'
            });
        };//init()
        
        var setAttributes = function (obj) {
            
            var img_title, img_src, style_class;
            
            if (obj.tunnel_status.toUpperCase() === 'ON') {
                img_title = 'Tunnel is ON (Click to turn OFF)';
                img_src = 'tunnel_on.png';
                style_class = 'tunnel_on';
            } else {
                img_title = 'Tunnel is OFF (Click to turn ON)';
                img_src = 'tunnel_off.png';
                style_class = 'tunnel_off';
            }
                    
            obj.style_class = style_class;
            obj.img_title = img_title;
            obj.img_src = img_src;
            obj.lastcheck = Sshmein.time.format(obj.lastcheck);
            
            return obj;
        };//setAttributes()
        
        var loadAll = function () {
            amplify.request('hosts', function (data) {
                for (var i=0; i<data.length; i++){
                    var host = setAttributes(data[i]);
    
                    Sshmein.collections.hosts.add(host.id, host);
                    
                    if (host.tunnel_status.toLowerCase() === 'on') {
                        Sshmein.collections.groups.incrementTunnelOnCounters(host.group_id);
                    }
                }
                
                amplify.publish('hosts.load');
            });
        };//loadAll()
        
        var add = function (hostId, obj) {
            store[hostId] = obj;
        };//add()
        
        var create = function (groupId) {
            amplify.request('host.create', {id: groupId}, function (data) {
                var host = setAttributes(data);
    
                add(host.id, host);
                amplify.publish('host.create', host.id);
            });
        };//create()
        
        var remove = function (hostId, fromDatabaseToo) {
            if (store[hostId].tunnel_status.toLowerCase() === 'on'){
                Sshmein.collections.groups.decrementTunnelOnCounters(store[hostId].group_id);
            }
            
            delete store[hostId];
            
            amplify.publish('host.remove', hostId);
            
            if (fromDatabaseToo !== false) {
                //Delete in database
                amplify.request('host.delete', {id : hostId});
            }
        };//remove()
        
        var update = function (hostId, property, value) {
            store[hostId][property] = value;
    
            var data = {id: hostId};
            data[property] = value;
            amplify.request('host.update', data);
            amplify.publish('host.update', {id: hostId, 'key': property, value: value});
        };//update()
        
        var getOne = function (hostId) {
            if (store[hostId]) {
                return store[hostId];
            }
        };//getOne()
        
        var getAll = function (asArray) {
            var obj;
            
            if (asArray === true) {
                var data = [];
                
                for (obj in store) {
                    if (store.hasOwnProperty(obj)){
                        data.push(store[obj]);
                    }
                }
                
                return data;
                
            } else {
                return store;
            }
        };//getAll()
        
        var removeAllByGroupId = function (groupId) {
            var hostId;
            
            for (hostId in store) {
                if (store.hasOwnProperty(hostId) && store[hostId].group_id == groupId) {
                    remove(hostId, false);
                }
            }
        };//removeAllByGroupId()
        
        var getGroupId = function (hostId) {
            return store[hostId].group_id;
        };//getGroupId()
    
        
        return {
            /* Hosts public methods */
            
            init : init,
            loadAll : loadAll,
            create : create,
            add : add,
            remove : remove,
            update : update,
            getOne : getOne,
            getAll : getAll,
            removeAllByGroupId : removeAllByGroupId,
            getGroupId : getGroupId,
            
            getAllAsArray : function () {
                return getAll(true);
            }//getAllAsArray()
            
        };//return object
    }());//Sshmein.collections.hosts
    
    
    /*
    * Models definition initialization
    */
    Sshmein.models = {
        init: function () {
            Sshmein.collections.groups.init();
            Sshmein.collections.hosts.init();
        }//init()
    };//Sshmein.models
    
    
    /*
    * Sshmein UI Groups
    */
    
    Sshmein.ui.groups = {
    
        load : function () {
            Sshmein.collections.groups.loadAll();
        },//load()
        
        add : function () {
            Sshmein.collections.groups.create();
        },//add()
        
        remove : function (groupId) {
        
            var groupEl = $('div#group_' + groupId);
            var title = groupEl.attr('data-groupname');
            
            //Requesting confirmation before deleting
            var resp = confirm('Are you sure you want to delete permanently\nthe group "' + title + '" and all his hosts?\n\nYou will not be able to access any computer of this group after the deletion');
            
            if (resp) {
                //Deleting group from collections
                Sshmein.collections.groups.remove(groupId);
    
                //Removing group from interface
                $('div#group_' + groupId).remove();
                       
                //Notification
                amplify.publish('notification', 'Deletion of group ' + title + ' OK!');
            }
        },//remove()
        
        renderAll : function () {
    
            var data = Sshmein.collections.groups.getAllAsArray();
                
            $('#groups').html('');
            
            $('#groupTemplate').tmpl(data).appendTo('#groups');
           
            $("#groups").multiAccordion('destroy');
            $("#groups").multiAccordion({active: 'none' });

            //Binding edit in place
            Sshmein.ui.groups.lateBinding();
                    
        },//render()
        
        
        renderOne: function (groupId) {
            var data = Sshmein.collections.groups.getOne(groupId);
            
            $('#groupTemplate').tmpl(data).prependTo('#groups');
            
            var activePanels = $('#groups').multiAccordion('getActiveTabs');

            $("#groups").multiAccordion('destroy');
            $("#groups").multiAccordion({active : activePanels});
             
            //Binding edit in place
            Sshmein.ui.groups.lateBinding();
            
        },//renderOne()
        
        updateGroupName : function (groupId, newName) {
            $('div#group_' + groupId).attr('data-groupname', newName);
            $('#delgroup_' + groupId).attr('title', 'Delete group ' + newName);
            $('td[data-group=' + groupId + ']', '#hosts').html(newName);
        },//updateGroupName()
        
        
        renderCounterOn: function (groupId) {
            var counters = Sshmein.collections.groups.getTunnelOnCounters();
            var tunnelOnCnt = counters[groupId];
            var text = (tunnelOnCnt ? 'Tunnel ON : ' + tunnelOnCnt : '');
    
            $('#tunnelON_' + groupId).html(text);
    
        },//renderCounterOn

        expandAll: function(){
            var closedGroups = $('#groups').find('div h3').filter(
                function(){
                    return $(this).hasClass('ui-state-default');
                }
            );

            closedGroups.each(function(){
                $(this).trigger('click');
            });
        },//expandAll()

        collapseAll:  function(){
            var openedGroups = $('#groups').find('div h3').filter(
                function(){
                    return $(this).hasClass('ui-state-active');
                }
            );

            openedGroups.each(function(){
                $(this).trigger('click');
            });
        },//collapseAll()
        
        lateBinding: function () {
            //Binding edit in place for group's name
            $('.editgroupname').editable(function (value) {
                Sshmein.collections.groups.update(this.id, 'name', value);
                return value;
                            
            }, {
                name : 'groupname',
                onblur : 'submit',
                style : 'width: 200px;',
                tooltip : 'Doubleclick to edit the group name',
                width: 'none',
                event: 'dblclick'
            });
            
            //Binding edit in place for group's description
            $('.editgroupdescription').editable(function (value) {
                Sshmein.collections.groups.update(this.id, 'description', value);
                return value;
            }, {
                name : 'description',
                type : 'textarea',
                rows : 3,
                submit: 'OK',
                tooltip : 'Click to edit the group description'
            });
        },
        
        events : function () {
            //Binding event for delete group image
            $('#groups').delegate('a.delgroup', 'click', function () {
                Sshmein.ui.groups.remove($(this).attr('id').substring(9));
            });
            
            //Binding event for New host button
            $('#groups').delegate('button.new_host', 'click', function () {
                Sshmein.collections.hosts.create($(this).attr('id').substring(13));
            });
            
            /*
            * Binding event for view buttons
            */
            //View ALL
            $('#groups').delegate('button.view_all', 'click', function () {
                $('dl.host').show();
                $(this).parents('.filter:first').find(".ui-state-active").removeClass("ui-state-active");
                $(this).addClass('ui-state-active');
            });
            
            //View ON
            $('#groups').delegate('button.view_on', 'click', function () {
                $('dl.tunnel_on').show();
                $('dl.tunnel_off').hide();
                $(this).parents('.filter:first').find(".ui-state-active").removeClass("ui-state-active");
                $(this).addClass('ui-state-active');
            });
            
            //View OFF
            $('#groups').delegate('button.view_off', 'click', function () {
                $('dl.tunnel_off').show();
                $('dl.tunnel_on').hide();
                $(this).parents('.filter:first').find(".ui-state-active").removeClass("ui-state-active");
                $(this).addClass('ui-state-active');
            });

            $('#groups').delegate('dl','hover', function(event){
                if (event.type === 'mouseenter'){
                    $(this).addClass('ui-state-active ui-corner-all');
                }else{
                    $(this).removeClass('ui-state-active ui-corner-all');
                }
            });
            
            $('#groups').delegate('button', 'hover', function (event){
                if (event.type === 'mouseenter'){
                    $(this).addClass('ui-state-hover');
                }else{
                    $(this).removeClass('ui-state-hover');
                }
            });

            //Binding click expand All
            $('#expandAll').click(function () {
                Sshmein.ui.groups.expandAll();
            });

            //Binding click collapse All
            $('#collapseAll').click(function () {
                Sshmein.ui.groups.collapseAll();
            });
        }//events
    };//Sshmein.ui.groups
    
    /*
    * Sshmein UI hosts
    */
    
    Sshmein.ui.hosts = {
        load : function () {
            Sshmein.collections.hosts.loadAll();
        },//load()
        
        add : function () {
            Sshmein.collections.hosts.create();
        },//add()
          
        destroy : function (hostId) {
                
            var title = Sshmein.collections.hosts.getOne(hostId).hostname;

            //Requesting confirmation before deleting
            var resp = confirm('Are you sure you want to delete permanently\nthe host "' + title + '"?');
            
            if (resp) {
                //Removing from collections
                Sshmein.collections.hosts.remove(hostId);
                            
                //Notification
                amplify.publish('notification', 'Deleting host ' + title + ' OK!');
            }
        },//destroy()

        remove : function(hostId){
            $('[data-host=' + hostId + ']').remove();
        },//remove()
        
        renderAll : function () {
            var row;
            
            var data = Sshmein.collections.hosts.getAll();
            
            /* Clear hosts content */
            var hostsContainer = $('#hosts tbody');
            hostsContainer.html('');

            for (row in data) {
                Sshmein.ui.sidebar.updateList(data[row].id, data[row].tunnel_status);
                
                var groupId = '#group_' + data[row].group_id;
                data[row].groupname = Sshmein.collections.groups.getOne(data[row].group_id).name;
                
                /* Add host in tile view*/
                $('#hostTemplate').tmpl(data[row]).appendTo(groupId + ' div.hosts');
                
                /* Add host in detail view*/

                $('#hostTemplateRow').tmpl(data[row]).appendTo(hostsContainer);
            }
            
            //Binding edit in place
            Sshmein.ui.hosts.lateBinding();
    
        },//renderAll
        
        renderOne: function (hostId) {
            var data = Sshmein.collections.hosts.getOne(hostId);
            data.groupname = Sshmein.collections.groups.getOne(data.group_id).name;
    
            /* Add host in tile view*/
            $('#hostTemplate').tmpl(data).insertAfter('#group_' + data.group_id + ' div.hosts div.ui-widget-header');

            /* Add host in detail view*/
            $('#hostTemplateRow').tmpl(data).appendTo('#hosts tbody');
             
            //Binding edit in place
            Sshmein.ui.hosts.lateBinding();
            
        },//renderOne()
        
        tunnelStatus: function (hostId, value) {
            var state = (value === 'ON' ? 'on' : 'off');
            var reverseState = value === 'ON' ? 'OFF' : 'ON';
            var hostname = Sshmein.collections.hosts.getOne(hostId).hostname;
            var notificationType = ( state == 'off' ? 'error' : 'success' );
            var icon = $('.tunnel', '[data-host=' + hostId + ']');
    
            $('[data-host=' + hostId +']').attr('class', 'host tunnel_' + state);
            icon.attr('src', 'static/images/tunnel_' + state + '.png');
            icon.attr('class', 'tunnel tunnel_' + state);
            icon.attr('title', 'Tunnel is ' + state + ' (Click to turn ' + reverseState + ')');

            amplify.publish('notification', 'Turning ' + state.toUpperCase() + ' tunnel OK!', hostname, notificationType );
        },
        
        updateHostName: function (hostId, newName) {
            $('img.delete','[data-host=' + hostId + ']').attr('title', 'Delete ' + newName);
            $('a.download img','[data-host=' + hostId + ']').attr('title', "Download tunnel's client for " + newName);
            $('[data-host=' + hostId + ']').find('.edit_hostname').html(newName);
        },//updateHostName()

        updateGatewayHost: function(hostId, gateway){
            $('[data-host=' + hostId + ']').find('.edit_gateway_host').html(gateway);
        },

        updateGatewayPort: function(hostId, port){
            $('[data-host=' + hostId + ']').find('.edit_gateway_port').html(port);
        },

        updateGatewayUser: function(hostId, user){
            $('[data-host=' + hostId + ']').find('.edit_gateway_user').html(user);
        },

        viewAll : function(){
            $('tr', '#hosts').each(function(){
                $(this).show();
            });
        },

        viewOn : function(){
            this.viewAll();
            $('img.tunnel_off', '#hosts').each(function(){
                $(this).parents('tr').hide();
            });
        },

        viewOff : function(){
            this.viewAll();
            $('img.tunnel_on', '#hosts').each(function(){
                $(this).parents('tr').hide();
            });
        },
        
        lateBinding : function () {
            $('.edit_hostname').editable(function (value) {
                var hostId = $(this).parents('[data-host]').attr('data-host');
                Sshmein.collections.hosts.update(hostId, 'hostname', value);
                return value;
            }, {
                name : 'hostname',
                onblur : 'submit',
                tooltip : 'Click to edit hostname',
                style: "display:inline",
                cssclass: "hostname",
                width: "none"
            });
        
            $('.edit_gateway_host').editable(function (value) {
                var hostId = $(this).parents('[data-host]').attr('data-host');
                Sshmein.collections.hosts.update(hostId, 'gateway_host', value);
                return value;
            }, {
                name : 'gateway_host',
                onblur : 'submit',
                tooltip : 'Click to edit tunnel gateway',
                style: "display:inline"
            });
            
            $('.edit_gateway_port').editable(function (value) {
                var hostId = $(this).parents('[data-host]').attr('data-host');
                Sshmein.collections.hosts.update(hostId, 'gateway_port', value);
                return value;
            }, {
                name : 'gateway_port',
                onblur : 'submit',
                tooltip : 'Click to edit the tunnel gateway port',
                style: "display:inline",
                width:"50px"
            });
            
            $('.edit_gateway_user').editable(function (value) {
                var hostId = $(this).parents('[data-host]').attr('data-host');
                Sshmein.collections.hosts.update(hostId, 'gateway_user', value);
                return value;
            }, {
                name : 'gateway_user',
                onblur : 'submit',
                tooltip : 'Click to edit the tunnel gateway user',
                style: "display:inline",
                width:"30px"
            });
            
            $('.edit_authorized_ip').editable(function (value) {
                var hostId = $(this).parents('[data-host]').attr('data-host');
                Sshmein.collections.hosts.update(hostId, 'authorized_ip', value);
                return value;
            }, {
                name : 'authorized_ip',
                onblur : 'submit',
                tooltip : 'Click to edit the authorized IP',
                style: "display:inline"
                    
            });
        },//lateBinding()
        
        events : function () {
           
            $('#groups, #hosts').delegate('img.tunnel_on', 'click', function () {
                var hostId = $(this).parents('[data-host]').attr('data-host');
                Sshmein.collections.hosts.update(hostId, 'tunnel_status', 'OFF');
            });
            
            $('#groups, #hosts').delegate('img.tunnel_off', 'click', function () {
                var hostId = $(this).parents('[data-host]').attr('data-host');
                Sshmein.collections.hosts.update(hostId, 'tunnel_status', 'ON');
            });
            
            $('#groups, #hosts').delegate('img.delete', 'click', function () {
                var hostId = $(this).parents('[data-host]').attr('data-host');
                Sshmein.ui.hosts.destroy(hostId);
            });
            
            $('#hosts').delegate('[data-group]', 'click', function () {
                var groupId = $(this).attr('data-group');
                Sshmein.ui.actions.openGroup(groupId);
            });

            $('#hosts tbody').delegate('tr','hover', function(event){
                if (event.type === 'mouseenter'){
                    $(this).addClass('ui-state-active');
                }else{
                    $(this).removeClass('ui-state-active');
                }
            });

            $('.view_all', '#hosts-toolbar').click(function(){
                $(this).parent().find(".ui-state-active").removeClass("ui-state-active");
                $(this).addClass('ui-state-active');
                Sshmein.ui.hosts.viewAll();
            });

            $('.view_on', '#hosts-toolbar').click(function(){
                $(this).parent().find(".ui-state-active").removeClass("ui-state-active");
                $(this).addClass('ui-state-active');
                Sshmein.ui.hosts.viewOn();
            });

            $('.view_off', '#hosts-toolbar').click(function(){
                $(this).parent().find(".ui-state-active").removeClass("ui-state-active");
                $(this).addClass('ui-state-active');
                Sshmein.ui.hosts.viewOff();
            });

        }//events()
    };//Sshmein.ui.hosts
    
    /*
    * Sshmein UI sidebar
    */
    
    Sshmein.ui.sidebar = (function () {
        
        var tunnelOnCounter = 0;
        
        var renderCounter = function () {
            $('p#tunnel_on_count span').html(tunnelOnCounter);
        };//_renderCounter()
        
        var incrementCounter = function () {
            tunnelOnCounter++;
            renderCounter();
        };//incrementCounter()
        
        var decrementCounter = function () {
            tunnelOnCounter--;
            tunnelOnCounter = tunnelOnCounter < 0 ? 0 : tunnelOnCounter;
            renderCounter();
        };//decrementCounter()
        
        var updateGroupName = function (groupId, groupName) {
            var el = $('div#sidebar_info li[data-group=' + groupId + ']');
            
            if (el) {
                el.attr('title', groupName);
            }
        };//updateGroupName()
        
        var updateHostName = function (hostId, newName) {
                 
            var  elem = $('div#sidebar_info li[data-host=' + hostId + '] a');

            if (elem) {
                elem.html(newName.htmlEntities());
            }
        };//updateHostName()
        
        var removeHost = function (hostId) {

            var elem = $('div#sidebar_info li[data-host=' + hostId + ']');
                    
            if (elem.length === 1) {
                elem.remove();
                decrementCounter();
            }
    
        };//removeHost();
        
        var addHost = function (hostId) {

            var host = Sshmein.collections.hosts.getOne(hostId);
            var groupname = Sshmein.collections.groups.getOne(host.group_id).name;
            
            if ($('div#sidebar_info li[data-host=' + hostId + ']').length === 0) {
                $('div#sidebar_info ul').append('<li data-host="' + hostId + '" data-group="' + host.group_id + '" title="' + groupname + '"><a href="#">' + host.hostname + '</a></li>');
                incrementCounter();
            }
        };//addHost();
        
        var updateList = function (hostId, tunnelStatus) {
            if (tunnelStatus.toLowerCase() === 'on') {
                addHost(hostId);
            } else {
                removeHost(hostId);
            }
        };//updateList()
        
        return {
            
            updateList : updateList,
            updateGroupName : updateGroupName,
            updateHostName : updateHostName
            
        };//return
    }());//Sshmein.ui.sidebar

    Sshmein.ui.actions =(function () {

        var toggleView = function(view){

            var mode = view || Sshmein.settings.get('displayMode');

            Sshmein.settings.set('displayMode', view);

            amplify.publish('toggle.view', mode);

        };

        var refresh = function(){
            amplify.publish('notification','Refreshing groups and hosts...', '', 'info');
            amplify.publish('refresh');
            Sshmein.collections.groups.loadAll();
        };

        var openGroup = function (groupId) {
            Sshmein.ui.actions.toggleView('groups');
            var groupEl = '#group_' + groupId;
            var h3 = $('h3', groupEl);
            var isClosed = h3.hasClass('ui-state-default');

            if (isClosed){
                h3.trigger('click');
            }
        };//openGroup()

        var searchHost = function(){
            var elem = $('input[name=searchHost]');
            var hostname = elem.val();

            if (hostname){
                var elements = $('.edit_hostname:contains("' + hostname +'")', '#groups').filter(
                    function(){
                        return $(this).html() == hostname;
                    }
                );

                if (elements){
                    Sshmein.ui.groups.collapseAll();

                    elements.each(function(){
                        var hostId = $(this).parents('dl').attr('data-host');
                        var groupId = Sshmein.collections.hosts.getOne(hostId).group_id;
                        openGroup(groupId);
                    });
                }

                elem.val('');

            }
        };//searchHost()

        return {
            
            toggleView : toggleView,
            refresh : refresh,
            openGroup: openGroup,
            searchHost: searchHost
        };//return
    }());//Sshmein.ui.actions

    Sshmein.ui.events = function () {
        //Hover effect for the logout button
        $('#logout, button').hover(function () {
            $(this).addClass('ui-state-hover');
        }, function () {
            $(this).removeClass('ui-state-hover');
        });
        
        //Binding logout event to logout button
        $('#logout').click(function () {
            /*Nothing here now!*/
        });
        
        //Binding click 'New group' button
        $('button#new_group').click(function () {
            Sshmein.ui.groups.add();
        });

        //Binding click 'Refresh' button
        $('button#refresh').click(function () {
            Sshmein.ui.actions.refresh();
        });
        
        //Binding sidebar's href to openGroup functionnality
        $('#sidebar_info').delegate('a', 'click', function () {
            var groupId = $(this).parent().attr('data-group');
            Sshmein.ui.actions.openGroup(groupId);
        });

        //Binding click View by Groups button
        $('button#displayByGroups').click(function () {
            Sshmein.ui.actions.toggleView('groups');
        });
        
        //Binding click View by Hosts button
        $('button#displayByHosts').click(function () {
            Sshmein.ui.actions.toggleView('hosts');
        });

        //Binding Keypress (enter) on search host input
        $('input[name=searchHost]').keyup(function(evt){
            if (evt.which === 13){
                Sshmein.ui.actions.searchHost();
            }
        });

        //All group's events
        Sshmein.ui.groups.events();
        
        //All host's events
        Sshmein.ui.hosts.events();
    
    };//Sshmein.ui.events
    
    Sshmein.subscriptions = function () {
        amplify.subscribe('groups.load', function () {
            if (Sshmein.collections.groups.getAll()) {
                Sshmein.ui.groups.renderAll();
                Sshmein.ui.hosts.load();
            } else {
                $('#loadingDiv').dialog('destroy');
            }
        });
        
        amplify.subscribe('group.create', function (groupId) {
            Sshmein.ui.groups.renderOne(groupId);
        });
        
        amplify.subscribe('group.update', function (obj) {
            var groupId = obj.id;
            var property = obj.key;
            var value = obj.value;
            
            switch (property){
                case 'name':
                    Sshmein.ui.sidebar.updateGroupName(groupId, value);
                    Sshmein.ui.groups.updateGroupName(groupId, value);
                break;
            }
        });
        
        amplify.subscribe('hosts.load', function () {
            Sshmein.ui.hosts.renderAll();
            $('#loadingDiv').dialog('destroy');
        });
        
        amplify.subscribe('host.create', function (hostId) {
            Sshmein.ui.hosts.renderOne(hostId);
        });
        
        amplify.subscribe('notification', function (msg, title, type) {
            Sshmein.notifiate(msg, title, type);
        });
        
        amplify.subscribe('host.remove', function (hostId) {
            Sshmein.ui.sidebar.updateList(hostId, 'off');
            Sshmein.ui.hosts.remove(hostId);
        });
        
        amplify.subscribe('host.update', function (obj) {
            var hostId = obj.id;
            var property = obj.key;
            var value = obj.value;
            
            switch (property) {
                case 'tunnel_status':
                    Sshmein.ui.hosts.tunnelStatus(hostId, value);
                    Sshmein.ui.sidebar.updateList(hostId, value);
                    
                    var groupId = Sshmein.collections.hosts.getGroupId(hostId);
                    
                    if (value.toLowerCase() === 'on') {
                        Sshmein.collections.groups.incrementTunnelOnCounters(groupId);
                    } else {
                        Sshmein.collections.groups.decrementTunnelOnCounters(groupId);
                    }
                break;
                
                case 'hostname':
                    Sshmein.ui.sidebar.updateHostName(hostId, value);
                    Sshmein.ui.hosts.updateHostName(hostId, value);
                break;

                case 'gateway_host':
                    Sshmein.ui.hosts.updateGatewayHost(hostId, value);
                break;
                
                case 'gateway_port':
                    Sshmein.ui.hosts.updateGatewayPort(hostId, value);
                break;

                case 'gateway_user':
                    Sshmein.ui.hosts.updateGatewayUser(hostId, value);
                break;
            }
        });
        
        amplify.subscribe('group.counterOn.update', function (groupId) {
            Sshmein.ui.groups.renderCounterOn(groupId);
        });


        amplify.subscribe('toggle.view', function(mode){
            if (mode === 'groups'){
                $('#groups-wrapper').show();
                $('#hosts-wrapper').hide();
                $('button#displayByHosts').removeClass("ui-state-active");
                $('button#displayByGroups').addClass('ui-state-active');
            }else{
                $('#groups-wrapper').hide();
                $('#hosts-wrapper').show();
                $('button#displayByHosts').addClass("ui-state-active");
                $('button#displayByGroups').removeClass('ui-state-active');
            }
        });

        amplify.subscribe('refresh', function () {
            $('.filter', '#hosts-toolbar').find(".ui-state-active").removeClass("ui-state-active");
            $('.view_all', '#hosts-toolbar').addClass('ui-state-active');
        });
    };//Sshmein.subscriptions

    Sshmein.notifiate = function (msg, title, type) {

        type = type || 'success';
        title = title || '';

        switch(type){
            case 'success':
                Notifier.success(msg, title);
            break;

            case 'info':
                Notifier.info(msg, title);
            break;
            
            case 'warning':
                Notifier.warning(msg, title);
            break;

            case 'error':
                Notifier.error(msg, title);
            break;
        }
    };//notifiate()
    
    Sshmein.time = {
	
		format: function(unixstamp){
            if (unixstamp){
                var stamp = new Date(parseInt(unixstamp, 10) * 1000);
                return stamp.toLocaleString();
			}else{
                return '';
			}
		}//format()
	};//Sshmein.time
	
    Sshmein.run = function () {
        /*
        * Starting SSHMeIn
        */
        $('#loadingDiv').dialog({modal: true, resizable: false, title: 'Loading SSHMeIn interface', height: 100, width: 400}).show();
        $('#switcher').themeswitcher({loadTheme: Sshmein.settings.get('theme')});

        //Set NotifierJs config
        NotifierjsConfig.defaultTimeOut = Sshmein.settings.get('notificationDelay');
        NotifierjsConfig.notificationStyles.opacity = Sshmein.settings.get('notificationOpacity');
        NotifierjsConfig.position = ["bottom", "right"];
        Sshmein.ui.actions.toggleView(Sshmein.settings.get('displayMode'));

        this.subscriptions();
        this.models.init();
        this.ui.events();
        this.ui.groups.load();
    };//Sshmein.run

}(jQuery, amplify));

